local clear = reload("table.opt.clear")
local akeys = reload("map.akeys")
local newt = reload("newt")
local delt = reload("delt")
local cache = newt()

---插入函数
local function uinsert(tname, sfields, ...)
    ---集合
    local map = cache[tname] or newt()
    cache[tname] = map
    ---列表
    local list = map[sfields] or newt()
    map[sfields] = list
    if not next(list) then
        local fmt = "insert into %s(%s)values"
        fmt = fmt:format(tname, sfields)
        table.insert(list, fmt)
    end
    ---参数
    local args = newt()
    local count = select('#', ...)
    for i = 1, count do
        local arg = select(i, ...)
        if nil == arg then
            arg = 'NULL'
        elseif false == arg then
            arg = '0'
        elseif true == arg then
            arg = '1'
        end
        table.insert(args, arg)
    end
    local strarg = table.concat(args, ',')
    table.insert(list, '(')
    table.insert(list, strarg)
    table.insert(list, ')')
    table.insert(list, ',\n')
    delt(args)
end

---完成联合
local function concat(tname, sfields, tflist)
    ---集合
    local map = cache[tname] or newt()
    cache[tname] = map
    ---列表
    local list = map[sfields] or newt()
    map[sfields] = list
    if not next(list) then
        return
    end
    table.remove(list)
    table.insert(list, "\non duplicate key update \n")
    local flen = #tflist
    for i = 1, flen do
        local field = tflist[i]
        table.insert(list, field)
        table.insert(list, '=values(')
        table.insert(list, field)
        table.insert(list, '),\n')
    end
    local len = #list
    list[len] = ');'
    local sql = table.concat(list)
    clear(list)
    return sql
end

---生成函数
---@param tname string 表名
---@param tfields string[] 字段表
---@return function appendf(...) 追加函数
---@return function concatf() 完成联合函数
local function generic(tname, tfields)
    local tflist = akeys(tfields, newt())
    local fcount = #tflist
    local sfields = table.concat(tflist, ',')
    local function appendf(...)
        return uinsert(tname, sfields, fcount, ...)
    end
    local function concatf()
        return concat(tname, sfields, tflist, fcount)
    end
    return appendf, concatf
end

return generic
